package cn.com.cifi.mars.service.impl;

import cn.com.cifi.mars.bean.vo.report.ProjectReturnCoefficientReportVo;
import cn.com.cifi.mars.bean.vo.report.VsCoefficientReportVo;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.entity.DmProjectReturnCoefficient;
import cn.com.cifi.mars.entity.ProjectReturnCoefficient;
import cn.com.cifi.mars.entity.ReturnCoefficientDetail;
import cn.com.cifi.mars.mapper.mars.DmProjectReturnCoefficientMapper;
import cn.com.cifi.mars.mapper.wrapper.ReturnCoefficientDetailWrapper;
import cn.com.cifi.mars.service.DmProjectReturnCoefficientReportService;
import cn.com.cifi.mars.util.MyMapUtils;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: JingYuanXiang
 * @date: 2020/12/15 17:14
 */
@Slf4j
@Service
public class DmProjectReturnCoefficientReportServiceImpl implements DmProjectReturnCoefficientReportService {

    @Autowired
    private DmProjectReturnCoefficientMapper dmProjectReturnCoefficientMapper;

    @Autowired
    private ReturnCoefficientDetailWrapper returnCoefficientDetailWrapper;


    /**
     * 刷新项目回款系数分析表数据
     *
     * @param projectId 项目id
     * @param yearMonth 年月
     */
    @Transactional
    @Override
    public void refreshdmProjectReturnCoefficient(String projectId, String yearMonth) {
        if (StringUtils.isEmpty(yearMonth)) {
            throw new MsgException(CodeEnum.REQUEST_PARAM_NOT_FULL_ERROR);
        }

        //查询各项目id及版本类型下最新版本
        List<ProjectReturnCoefficient> projectReturnCoefficientList = dmProjectReturnCoefficientMapper.selectNewestVersionGroupByProjectIdAndVersionType(projectId, yearMonth);
        if (CollectionUtils.isEmpty(projectReturnCoefficientList)) {
            return;
        }
        //转换map(key:项目回款系数版本id,value:项目回款系数版本)
        Map<String, ProjectReturnCoefficient> projectReturnCoefficientMap = projectReturnCoefficientList.stream().collect(Collectors.toMap(ProjectReturnCoefficient::getId, s -> s));
        //回款系数详情列表
        List<ReturnCoefficientDetail> returnCoefficientDetailList = returnCoefficientDetailWrapper.selectByCoefficientIdList(new ArrayList<>(projectReturnCoefficientMap.keySet()), IsDeleteEnum.NO.getKey());
        //转换map(key:项目回款系数版本id,value:回款系数详情列表)
        Map<String, List<ReturnCoefficientDetail>> returnCoefficientDetailMap = returnCoefficientDetailList.stream().collect(Collectors.groupingBy(ReturnCoefficientDetail::getCoefficientId));


        List<DmProjectReturnCoefficient> dmProjectReturnCoefficientList = new ArrayList<>();
        for (Map.Entry<String, ProjectReturnCoefficient> projectReturnCoefficientEntry : projectReturnCoefficientMap.entrySet()) {
            String projectReturnCoefficientId = projectReturnCoefficientEntry.getKey();
            ProjectReturnCoefficient projectReturnCoefficient = projectReturnCoefficientEntry.getValue();
            List<ReturnCoefficientDetail> returnCoefficientDetails = returnCoefficientDetailMap.get(projectReturnCoefficientId);
            for (ReturnCoefficientDetail detail : returnCoefficientDetails) {
                DmProjectReturnCoefficient dmProjectReturnCoefficient = new DmProjectReturnCoefficient();

                dmProjectReturnCoefficient.setAffiliationMonth(yearMonth);
                dmProjectReturnCoefficient.setRegionId(projectReturnCoefficient.getRegionId());
                dmProjectReturnCoefficient.setRegionName(projectReturnCoefficient.getRegionName());
                dmProjectReturnCoefficient.setCityCompanyId(projectReturnCoefficient.getCityCompanyId());
                dmProjectReturnCoefficient.setCityCompanyName(projectReturnCoefficient.getCityCompanyName());
                dmProjectReturnCoefficient.setProjectId(projectReturnCoefficient.getProjectId());
                dmProjectReturnCoefficient.setProjectCode(projectReturnCoefficient.getProjectCode());
                dmProjectReturnCoefficient.setProjectName(projectReturnCoefficient.getProjectName());
                dmProjectReturnCoefficient.setVersionType(projectReturnCoefficient.getVersionType());
                dmProjectReturnCoefficient.setProProductCode(detail.getProProductCode());
                dmProjectReturnCoefficient.setProProductType(detail.getProProductType());
                dmProjectReturnCoefficient.setOneMonth(detail.getOneMonth());
                dmProjectReturnCoefficient.setTwoMonth(detail.getTwoMonth());
                dmProjectReturnCoefficient.setThreeMonth(detail.getThreeMonth());
                dmProjectReturnCoefficient.setFourMonth(detail.getFourMonth());
                dmProjectReturnCoefficient.setFiveMonth(detail.getFiveMonth());
                dmProjectReturnCoefficient.setSixMonth(detail.getSixMonth());
                dmProjectReturnCoefficient.setSevenMonth(detail.getSevenMonth());
                dmProjectReturnCoefficient.setEightMonth(detail.getEightMonth());
                dmProjectReturnCoefficient.setNineMonth(detail.getNineMonth());
                dmProjectReturnCoefficient.setTenMonth(detail.getTenMonth());
                dmProjectReturnCoefficient.setElevenMonth(detail.getElevenMonth());
                dmProjectReturnCoefficient.setTwelveMonth(detail.getTwelveMonth());
                dmProjectReturnCoefficient.setThirteenMonth(detail.getThirteenMonth());
                dmProjectReturnCoefficient.setFourteenMonth(detail.getFourteenMonth());
                dmProjectReturnCoefficient.setFifteenMonth(detail.getFifteenMonth());
                dmProjectReturnCoefficient.setSixteenMonth(detail.getSixteenMonth());
                dmProjectReturnCoefficient.setSeventeenMonth(detail.getSeventeenMonth());
                dmProjectReturnCoefficient.setEighteenMonth(detail.getEighteenMonth());
                dmProjectReturnCoefficient.setNineteenMonth(detail.getNineteenMonth());
                dmProjectReturnCoefficient.setTwentyMonth(detail.getTwentyMonth());
                dmProjectReturnCoefficient.setTwentyOneMonth(detail.getTwentyOneMonth());
                dmProjectReturnCoefficient.setTwentyTwoMonth(detail.getTwentyTwoMonth());
                dmProjectReturnCoefficient.setTwentyThreeMonth(detail.getTwentyThreeMonth());
                dmProjectReturnCoefficient.setTwentyFourMonth(detail.getTwentyFourMonth());
                dmProjectReturnCoefficientList.add(dmProjectReturnCoefficient);
            }
        }

        //删除项目回款系数分析表数据
        delByYearMonthAndProjectId(yearMonth, projectId);
        //写入项目回款系数分析表数据
        dmProjectReturnCoefficientMapper.insertList(dmProjectReturnCoefficientList);
    }

    /**
     * 删除项目回款系数分析表数据
     *
     * @param yearMonth 年月
     * @param projectId 项目id
     */
    private void delByYearMonthAndProjectId(String yearMonth, String projectId) {
        QueryWrapper<DmProjectReturnCoefficient> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("affiliation_month", yearMonth).eq(StringUtils.isNotEmpty(projectId), "project_id", projectId);
        dmProjectReturnCoefficientMapper.delete(queryWrapper);
    }

    /**
     * 查询项目回款系数分析表数据
     * @param projectIdList 项目id列表
     * @param yearMonth     年月
     * @param versionType   版本类型
     * @param vsVersionType VS版本类型
     * @return
     */
    @Override
    public List<ProjectReturnCoefficientReportVo> dmProjectReturnCoefficient(List<String> projectIdList, String yearMonth, String versionType, String vsVersionType) {
        if (StringUtils.isEmpty(yearMonth) || StringUtils.isEmpty(versionType) || StringUtils.isEmpty(vsVersionType)) {
            throw new MsgException(CodeEnum.REQUEST_PARAM_NOT_FULL_ERROR);
        }
        //查询项目回款系数列表
        List<DmProjectReturnCoefficient> coefficientList = dmProjectReturnCoefficientMapper.selectByAffiliationMonthAndVersionType(projectIdList,yearMonth, Arrays.asList(versionType, vsVersionType));
        if (CollectionUtils.isEmpty(coefficientList)) {
            return new ArrayList<>();
        }
        //转换Map(key:版本类型,value:(key:项目id,value:(key:标准业态编码,value:回款系数详情列表)))
        Map<String, Map<String, Map<String, DmProjectReturnCoefficient>>> dmCoefficientByVersionTypeMap = coefficientList.stream()
                .collect(Collectors.groupingBy(DmProjectReturnCoefficient::getVersionType,
                        Collectors.groupingBy(DmProjectReturnCoefficient::getProjectId, Collectors.toMap(DmProjectReturnCoefficient::getProProductCode, s -> s))));

        //转换Map(key:项目id,value:标准业态编码列表)
        Map<String, List<String>> proProductCodeListMap = coefficientList.stream()
                .filter(s -> versionType.equals(s.getVersionType()))
                .collect(Collectors.groupingBy(DmProjectReturnCoefficient::getProjectId, Collectors.mapping(DmProjectReturnCoefficient::getProProductCode, Collectors.toList())));

        List<ProjectReturnCoefficientReportVo> voList = new ArrayList<>();
        for (Map.Entry<String, List<String>> proProductCodeListEntry : proProductCodeListMap.entrySet()) {
            //项目id
            String projectId = proProductCodeListEntry.getKey();
            for (String proProductCode : proProductCodeListEntry.getValue()) {
                if (CollectionUtils.isEmpty(dmCoefficientByVersionTypeMap.get(versionType))) {
                    continue;
                }
                //当前系数
                DmProjectReturnCoefficient coefficient = dmCoefficientByVersionTypeMap.get(versionType).get(projectId).get(proProductCode);

                Map<Integer, Object> coefficientMap = coefficient.getCoefficientMap();
                Map<Integer, Object> vsCoefficientMap;
                if (CollectionUtils.isNotEmpty(dmCoefficientByVersionTypeMap.get(vsVersionType))
                        && CollectionUtils.isNotEmpty(dmCoefficientByVersionTypeMap.get(vsVersionType).get(projectId))
                        && null != dmCoefficientByVersionTypeMap.get(vsVersionType).get(projectId).get(proProductCode)) {
                    vsCoefficientMap = dmCoefficientByVersionTypeMap.get(vsVersionType).get(projectId).get(proProductCode).getCoefficientMap();
                } else {
                    vsCoefficientMap = MyMapUtils.getCoefficientMap();
                }

                List<VsCoefficientReportVo> vsList = new ArrayList<>();
                for (Map.Entry<Integer, Object> coefficientEntry : coefficientMap.entrySet()) {
                    VsCoefficientReportVo vo = new VsCoefficientReportVo();

                    Integer num = coefficientEntry.getKey();
                    Object coefficientValue = coefficientEntry.getValue();
                    Object vsCoefficientValue = vsCoefficientMap.get(num);
                    Object difference;
                    if (!"-".equals(coefficientValue) && !"-".equals(vsCoefficientValue)) {
                        difference = ((BigDecimal) coefficientValue).subtract((BigDecimal) vsCoefficientValue);
                    } else {
                        difference = "-";
                    }
                    vo.setNum(num);
                    vo.setCompare(coefficientValue);
                    vo.setBeCompared(vsCoefficientValue);
                    vo.setDifference(difference);
                    vsList.add(vo);
                }

                ProjectReturnCoefficientReportVo vo = new ProjectReturnCoefficientReportVo();
                vo.setRegionName(coefficient.getRegionName());
                vo.setCityCompanyName(coefficient.getCityCompanyName());
                vo.setProjectCode(coefficient.getProjectCode());
                vo.setProjectName(coefficient.getProjectName());
                vo.setProProductCode(coefficient.getProProductCode());
                vo.setProProductType(coefficient.getProProductType());
                vo.setVsList(vsList);
                voList.add(vo);
            }
        }
        return voList;
    }








}
